package com.tdam2011.grupo04.web;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;

import org.json.JSONException;
import org.json.JSONObject;

import com.tdam2011.grupo04.R;
import com.tdam2011.grupo04.Sql;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.*;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.Facebook.*;


public class ContactoWebFacebook extends Activity{
	private Handler mHandler = new Handler();
	
	public static final int LOGIN = Menu.FIRST;
	public static final int MENSAJE_PRIVADO = Menu.FIRST + 1;
	public static final int PUBLICAR_MURO = Menu.FIRST + 2;
	public static final int ASIGNAR_CONTACTOS_AMIGOS = Menu.FIRST + 3;
	public static final int ELMINAR_ASIGNACION_CONTACTO_AMIGO = Menu.FIRST + 4;
	
	// application id from facebook.com/developers
	public static final String APP_ID = "146284105514859";
	// log tag for any log.x statements
	public static final String TAG = "FACEBOOK CONNECT";
	// permissions array
	private static final String[] PERMS = new String[] { "publish_actions", "publish_stream", "email", "user_relationships", "user_online_presence" };
	// facebook vars
	private Facebook mFacebook;
	private AsyncFacebookRunner mAsyncRunner;
	// id text view
	private TextView txt_info;
	private TextView lbl_mensaje;
	private TextView txt_mensaje;
	
	private String contacto;
	private String cuenta;
 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		Bundle extras= getIntent().getExtras();
        if(extras != null)
        	contacto= (String)extras.get("contacto");
        
		  if (APP_ID == null || APP_ID.equals("")) {
		  	Util.showAlert(this, "Warning", "Facebook Applicaton ID must be "
		  			+ "specified before running");
		  }
		 
		  // Seteamos el layout
		  initLayout();
		  txt_info.setText("Por Favor, inicie sesi�n en Facebook");
		  
		  SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		  prefs.getString("Token", null);
		  mFacebook = new Facebook(APP_ID);
		  
		  mFacebook.setAccessToken(prefs.getString("Token", null));
		  	
		  if(mFacebook.isSessionValid())
				getCuenta();
			else
				cuenta = "";

		  mAsyncRunner = new AsyncFacebookRunner(mFacebook);
		  
		  setearControles();

	}
	
	
	public void setearControles(){		
		Sql sql = new Sql(ContactoWebFacebook.this);
		
		if(cuenta.equals("")){
			txt_info.setText("Inicie sesi�n desde el men�");
			txt_mensaje.setVisibility(View.INVISIBLE);
			lbl_mensaje.setVisibility(View.INVISIBLE);
		}
		
		else if (sql.getContactoAmigo(contacto, cuenta).getCount() == 0) {
			// no esta hecha la asignaci�n
			txt_info.setText("Este contacto no esta asociado a ningun amigo de facebook. Seleccione la opci�n Asignar Amigo desde el menu (Debe estar logeado en facebook).");
			lbl_mensaje.setVisibility(View.INVISIBLE);
			txt_mensaje.setVisibility(View.INVISIBLE);
		}

		else {

			if (mFacebook.isSessionValid()) {
				txt_info.setText("Usted inici� sesi�n. Escriba el mensaje y seleccione el m�todo de envio desde el menu");
				txt_mensaje.setVisibility(View.VISIBLE);
				lbl_mensaje.setVisibility(View.VISIBLE);
			} else {
				txt_info.setText("Inicie sesi�n desde el menu");
				txt_mensaje.setVisibility(View.INVISIBLE);
				lbl_mensaje.setVisibility(View.INVISIBLE);
			}
		}
		sql.close();
	}
	
	protected void initLayout() {
        setContentView(R.layout.facebook_principal);
        txt_info = (TextView) findViewById(R.id.lbl_info_facebook);
        lbl_mensaje = (TextView) findViewById(R.id.lbl_mensaje_facebook);
        txt_mensaje = (TextView) findViewById(R.id.txt_mensaje_facebook);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(Menu.NONE, LOGIN, Menu.NONE, "Iniciar Sesi�n");
		menu.add(Menu.NONE, MENSAJE_PRIVADO, Menu.NONE, "Mensaje Privado");
		menu.add(Menu.NONE, PUBLICAR_MURO, Menu.NONE, "Publicar en el muro");
		menu.add(Menu.NONE, ASIGNAR_CONTACTOS_AMIGOS, Menu.NONE, "Asignar Amigo");
		menu.add(Menu.NONE, ELMINAR_ASIGNACION_CONTACTO_AMIGO, Menu.NONE, "Eliminar Asignacion");
		return true;
	}
	
	@Override
	public void onResume(){
		super.onResume();
		setearControles();
		
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		alVolver(menu);
		//loginItem.setEnabled(true);
		return super.onPrepareOptionsMenu(menu);
	}
	
	public void alVolver(Menu menu){
		MenuItem loginItem = menu.findItem(Menu.FIRST);
		MenuItem publicarMuro = menu.findItem(PUBLICAR_MURO);
		Sql sql = new Sql(ContactoWebFacebook.this);
		int contactoCuentaEnBd = sql.getContactoAmigo(contacto, cuenta).getCount();
		
		if (mFacebook.isSessionValid() && contactoCuentaEnBd==0) {
			loginItem.setTitle("Cerrar Sesi�n");
			menu.getItem(ASIGNAR_CONTACTOS_AMIGOS-1).setEnabled(true);
			menu.getItem(ELMINAR_ASIGNACION_CONTACTO_AMIGO-1).setEnabled(false);
			menu.getItem(MENSAJE_PRIVADO-1).setEnabled(false);
			menu.getItem(PUBLICAR_MURO-1).setEnabled(false);
		}
		else if(mFacebook.isSessionValid() && contactoCuentaEnBd!=0){
			loginItem.setTitle("Cerrar Sesi�n");
			menu.getItem(MENSAJE_PRIVADO-1).setEnabled(true);
			menu.getItem(PUBLICAR_MURO-1).setEnabled(true);
			menu.getItem(ASIGNAR_CONTACTOS_AMIGOS-1).setEnabled(false);
			menu.getItem(ELMINAR_ASIGNACION_CONTACTO_AMIGO-1).setEnabled(true);
		}
			
		else if(!mFacebook.isSessionValid()) {
			loginItem.setTitle("Iniciar Sesi�n");
			menu.getItem(MENSAJE_PRIVADO-1).setEnabled(false);
			menu.getItem(PUBLICAR_MURO-1).setEnabled(false);
			menu.getItem(ASIGNAR_CONTACTOS_AMIGOS-1).setEnabled(false);
			menu.getItem(ELMINAR_ASIGNACION_CONTACTO_AMIGO-1).setEnabled(false);
		}
		
		sql.close();
		setearControles();
	}
	
	
	private void saveToken(String token){
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		prefs.edit().putString("Token", token).commit();
		}

	private void deleteToken(){
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		prefs.edit().remove("Token").commit();
		}
	
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int itemId = item.getItemId();
		switch (itemId) {
		case LOGIN:
			if (mFacebook.isSessionValid()) {
				txt_info.setText("Cerrando Sesi�n..");
				AsyncFacebookRunner asyncRunner = new AsyncFacebookRunner(
						mFacebook);
				asyncRunner.logout(this, new LogoutRequestListener());
				cuenta = "";
			} else {
				mFacebook.authorize(this, PERMS, new LoginDialogListener());
			}
			break;
		case PUBLICAR_MURO:
			mAsyncRunner.request("me", new PublicarMuroRequestListener());
			break;
		case MENSAJE_PRIVADO:
			Sql sql = new Sql(ContactoWebFacebook.this);
			Cursor cur = sql.getContactoAmigo(contacto, cuenta);
			cur.moveToFirst();
			String priv = cur.getString(cur.getColumnIndex("privado"));
			sql.close();
			
			if(priv.equals("0"))//false
				showDialog(1);
			else
				showDialog(2);
			break;
		case ASIGNAR_CONTACTOS_AMIGOS:
			Intent i = new Intent(this, AsignarContactoAmigo.class);
	        i.setType("plain/text");
			i.putExtra("contacto", contacto);
			startActivity(i);
			break;
		case ELMINAR_ASIGNACION_CONTACTO_AMIGO:
			eliminarAsignacionContacto();			
			break;
		default:
			return false;
		}
		return true;
	}
	
	public void eliminarAsignacionContacto(){
		Sql sql = new Sql(ContactoWebFacebook.this);
		sql.deleteOneContactoAmigo(contacto, cuenta);
		sql.close();
		Toast.makeText(this, "Se elimino la asignacion", Toast.LENGTH_SHORT).show();
		setearControles();
	}
	
	@Override
	protected Dialog onCreateDialog(int id){
		Dialog dialogo = null;
		if(id == 1){
			dialogo = crearDialogoConfirmacion();
		}
		else
			dialogo = crearDialogoPrivacidadNoHabilitada();
		return dialogo;
	}
	
	private Dialog crearDialogoPrivacidadNoHabilitada()
	{
	    AlertDialog.Builder builder = new AlertDialog.Builder(this);
	 
	    builder.setTitle("Error");
	    builder.setMessage("El amigo no permite recibir mensajes de facebook desde aplicaciones externas a facebook");
	    builder.setNeutralButton("Aceptar", new OnClickListener() {
	    public void onClick(DialogInterface dialog, int which) {
	    	dialog.cancel();
	    }
	    });
	 
	    return builder.create();
	}
	
	private Dialog crearDialogoConfirmacion()
	{
	    AlertDialog.Builder builder = new AlertDialog.Builder(this);
	 
	    builder.setTitle("Atenci�n");
	    builder.setMessage("Para enviar un mensaje privado es necesario abrir su cliente de correo electronico �Desea continuar?");
	    builder.setPositiveButton("Si", new OnClickListener() {
	    public void onClick(DialogInterface dialog, int which) {
			mAsyncRunner.request("me/events", new EventRequestListener());
	    	dialog.cancel();
	    }
	    });
	    builder.setNegativeButton("No", new OnClickListener() {
	    public void onClick(DialogInterface dialog, int which) {
	        dialog.cancel();
	    }
	    });
	 
	    return builder.create();
	}
	
	
	public void getCuenta(){
		Bundle bdle2 = new Bundle();
		bdle2.putString("fields", "id");
		String graphpath2 = "me";
		JSONObject json2;
		try {
			json2 = Util.parseJson(mFacebook.request(graphpath2,bdle2));
			cuenta = json2.getString("id");
		} catch (FacebookError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private class LoginDialogListener implements DialogListener {
		 
		public void onComplete(Bundle values) {
			getCuenta();
			saveToken(mFacebook.getAccessToken());
			setearControles();
		}
	 
		public void onFacebookError(FacebookError e) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onError(DialogError e) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onCancel() {
			// TODO Auto-generated method stub
	 
		}
	}
	
	private class LogoutRequestListener implements RequestListener {
		 
		public void onComplete(String response, Object state) {
			// Dispatch on its own thread
			deleteToken();
			mHandler.post(new Runnable() {
				public void run() {
					setearControles();
				}
			});
		}
	 
		public void onIOException(IOException e, Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onFileNotFoundException(FileNotFoundException e,
				Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onMalformedURLException(MalformedURLException e,
				Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onFacebookError(FacebookError e, Object state) {
			// TODO Auto-generated method stub
	 
		}
	}

	private class PublicarMuroRequestListener implements RequestListener {
		 
		 public void onComplete(String response, Object state) {
			 	Bundle parameters = new Bundle();
			 	String mensaje = txt_mensaje.getText().toString();
		        parameters.putString("message", mensaje);
		        //parameters.putString("description", "integrating stuff");
		        try {
		        	mFacebook.request("me");
		        	
		        	Sql sql = new Sql(ContactoWebFacebook.this);
		        	Cursor c = sql.getContactoAmigo(contacto, cuenta);
		        	c.moveToFirst();
		        	String amigo = c.getString(c.getColumnIndex("amigoID"));
		        	sql.close();
		        	
				response = mFacebook.request(amigo+"/feed", parameters, "POST");
				Log.d("Tests", "La respuesta fue: " + response);
				if (response == null || response.equals("") ||
					response.equals("false")) {
					//showToast("Blank response.");
					Toast.makeText(ContactoWebFacebook.this, "No se pudo firmar en el muro", Toast.LENGTH_SHORT).show();
				}
				else {
					Toast.makeText(ContactoWebFacebook.this, "Mensaje posteado en el muro de tu amigo", Toast.LENGTH_SHORT).show();
				}
				finish();
			} catch (Exception e) {
				//showToast("Failed to post to wall!");
				e.printStackTrace();
				finish();
			}
			 
			  }
		
		
		
//		  public void onComplete(String response, Object state) {
//		  	try {
//		  		// process the response here: executed in background thread
//		  		Log.d(TAG, "Response: " + response.toString());
//		  		JSONObject json = Util.parseJson(response);
//		  		final String id = json.getString("id");
//		 
//		  		// then post the processed result back to the UI thread
//		  		// if we do not do this, an runtime exception will be generated
//		  		// e.g. "CalledFromWrongThreadException: Only the original
//		  		// thread that created a view hierarchy can touch its views."
//		  		ContactoWebFacebook.this.runOnUiThread(new Runnable() {
//		  			public void run() {
//		  				//userID = id;
//		  				mText.setText("Hello there, " + id + "!");
//		  			}
//		  		});
//		  	} catch (JSONException e) {
//		  		Log.w(TAG, "JSON Error in response");
//		  	} catch (FacebookError e) {
//		  		Log.w(TAG, "Facebook Error: " + e.getMessage());
//		  	}
//		 
//		  }
		 
		  public void onIOException(IOException e, Object state) {
		  	// TODO Auto-generated method stub
		 
		  }
		 
		  public void onFileNotFoundException(FileNotFoundException e,
		  		Object state) {
		  	// TODO Auto-generated method stub
		 
		  }
		 
		  public void onMalformedURLException(MalformedURLException e,
		  		Object state) {
		  	// TODO Auto-generated method stub
		 
		  }
		 
		  public void onFacebookError(FacebookError e, Object state) {
		  	// TODO Auto-generated method stub
		 
		  }
		}
	
	private class EventRequestListener implements RequestListener {
		 
		@Override
		public void onComplete(String response, Object state) {
			Sql sql = new Sql(ContactoWebFacebook.this);
        	Cursor c = sql.getContactoAmigo(contacto, cuenta);
        	c.moveToFirst();
        	String amigo = c.getString(c.getColumnIndex("amigoID"));
			sql.close();
			
			Intent i = new Intent(Intent.ACTION_SEND);
			i.setType("message/rfc822");
			i.putExtra(Intent.EXTRA_EMAIL  , new String[]{amigo+"@facebook.com"});
			i.putExtra(Intent.EXTRA_SUBJECT, "Mensaje Enviado desde Facebook");
			i.putExtra(Intent.EXTRA_TEXT   , txt_mensaje.getText().toString());
			
			runOnUiThread(new Runnable() {
				public void run() {
					txt_mensaje.setText("");
				}
			});

			try {
			    startActivity(Intent.createChooser(i, "Enviar Email"));
			} catch (android.content.ActivityNotFoundException ex) {
			    Toast.makeText(ContactoWebFacebook.this, "No hay un cliente de E-Mail instalado", Toast.LENGTH_SHORT).show();
			}
			
		}
	 
		public void onIOException(IOException e, Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onFileNotFoundException(FileNotFoundException e,
				Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onMalformedURLException(MalformedURLException e,
				Object state) {
			// TODO Auto-generated method stub
	 
		}
	 
		public void onFacebookError(FacebookError e, Object state) {
			// TODO Auto-generated method stub
	 
		}

		
	}
}